package com.action.ui.view;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.TextView;

import com.tencent.map.lib.util.StringUtil;

import java.math.BigDecimal;
import java.math.BigInteger;

/**
 * Created by jiansheng.li on 2018/3/20.
 */

@SuppressLint("AppCompatCustomView")
public class NumberScrollTextView extends TextView {

    private int numLength = 8;
    /**
     * 起始值 默认 0
     */
    private String mNumStart = "0";
    /**
     * 结束值
     */
    private String mNumEnd;
    /**
     * 动画总时间 默认 1500 毫秒
     */
    private long mDuration = 1500;
    /**
     * 前缀
     */
    private String mPrefixString = "";
    /**
     * 后缀
     */
    private String mPostfixString = "";
    /**
     * 是否开启动画
     */
    private boolean isEnableAnim = true;
    /**
     * 是否是整数
     */
    private boolean isInt;
    private ValueAnimator animator;

    public NumberScrollTextView(Context context) {
        super(context);
    }

    public NumberScrollTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public NumberScrollTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public void setNumLength(int numLength) {
        this.numLength = numLength;
    }

    public void setNumberString(String number) {
        setNumberString(new BigDecimal(previewEnd).setScale(numLength, BigDecimal.ROUND_DOWN).toPlainString(), number);
        this.previewEnd = number;
    }

    private String previewEnd = "0.00000000";

    public void setNumberString(String numberStart, String numberEnd) {
        mNumStart = numberStart;
        mNumEnd = numberEnd;
        start();
    }

    public void setEnableAnim(boolean enableAnim) {
        isEnableAnim = enableAnim;
    }

    public void setDuration(long mDuration) {
        this.mDuration = mDuration;
    }

    public void setPrefixString(String mPrefixString) {
        this.mPrefixString = mPrefixString;
    }

    public void setPostfixString(String mPostfixString) {
        this.mPostfixString = mPostfixString;
    }

    /**
     * 校验数字的合法性
     *
     * @param numberStart 　开始的数字
     * @param numberEnd   　结束的数字
     * @return 合法性
     */
    private boolean checkNumString(String numberStart, String numberEnd) {

        String regexInteger = "-?\\d*";
        isInt = numberEnd.matches(regexInteger) && numberStart.matches(regexInteger);
        if (isInt) {
            BigInteger start = new BigInteger(numberStart);
            BigInteger end = new BigInteger(numberEnd);
            return end.compareTo(start) >= 0;
        }
        String regexDecimal = "-?[1-9]\\d*.\\d*|-?0.\\d*[1-9]\\d*";
        if ("0".equals(numberStart)) {
            if (numberEnd.matches(regexDecimal)) {
                BigDecimal start = new BigDecimal(numberStart);
                BigDecimal end = new BigDecimal(numberEnd);
                return end.compareTo(start) > 0;
            }
        }
        if (numberEnd.matches(regexDecimal) && numberStart.matches(regexDecimal)) {
            BigDecimal start = new BigDecimal(numberStart);
            BigDecimal end = new BigDecimal(numberEnd);
            return end.compareTo(start) > 0;
        }
        return false;
    }

    private void start() {
        if (StringUtil.isEmpty(mNumEnd) || StringUtil.isEmpty(mNumStart)) {
            return;
        }

        if (!isEnableAnim) {
            // 禁止动画
            setText(mPrefixString + format(new BigDecimal(mNumEnd)) + mPostfixString);
            return;
        }
        animator = ValueAnimator.ofObject(new BigDecimalEvaluator(numLength), new BigDecimal(mNumStart), new BigDecimal(mNumEnd));
        animator.setDuration(mDuration);
        animator.setInterpolator(new AccelerateDecelerateInterpolator());
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                BigDecimal value = ((BigDecimal) valueAnimator.getAnimatedValue()).setScale(numLength, BigDecimal.ROUND_DOWN);
                setText(mPrefixString + format(value) + mPostfixString);
            }
        });
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                setText(mNumEnd);
            }
        });
        animator.start();
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (animator != null) {
            animator.cancel();
        }
    }

    /**
     * 格式化 BigDecimal ,小数部分时保留两位小数并四舍五入
     *
     * @param bd 　BigDecimal
     * @return 格式化后的 String
     */
    private String format(BigDecimal bd) {
        return String.valueOf(bd.setScale(numLength, BigDecimal.ROUND_HALF_UP).toPlainString());
    }

    private static class BigDecimalEvaluator implements TypeEvaluator {
        private int numLength;

        public BigDecimalEvaluator() {
        }

        public BigDecimalEvaluator(int numLength) {

            this.numLength = numLength;
        }

        @Override
        public Object evaluate(float fraction, Object startValue, Object endValue) {
            BigDecimal start = ((BigDecimal) startValue).setScale(numLength, BigDecimal.ROUND_DOWN);
            BigDecimal end = ((BigDecimal) endValue).setScale(numLength, BigDecimal.ROUND_DOWN);
            BigDecimal result = end.subtract(start).setScale(numLength, BigDecimal.ROUND_DOWN);
            return result.multiply(new BigDecimal("" + fraction)).add(start).setScale(numLength, BigDecimal.ROUND_DOWN);
        }
    }
}